package org.zecontech.extraplus.datagen;

import net.minecraft.client.resources.model.EquipmentClientInfo;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import org.zecontech.extraplus.ExtraPlus;
import org.zecontech.extraplus.util.Helpers;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;

// 模组装备资源数据生成
public class ModEquipmentInfoProvider implements DataProvider {

    private final PackOutput.PathProvider pathProvider;

    public ModEquipmentInfoProvider(PackOutput output) {
        this.pathProvider = output.createPathProvider(PackOutput.Target.RESOURCE_PACK, "equipment");
    }


    /**
     * 添加装备Json
     * @param registrar 注册器
     * @param name 装备名称
     */
    private void add(BiConsumer<ResourceLocation, EquipmentClientInfo> registrar, String name, boolean hasHorseArmor) {
        var builder = EquipmentClientInfo.builder();
        if (hasHorseArmor) {
            registrar.accept(
                    Helpers.identifier(name),
                    builder
                            .addLayers(
                                    EquipmentClientInfo.LayerType.HUMANOID,
                                    new EquipmentClientInfo.Layer(
                                            Helpers.identifier(name),
                                            Optional.empty(),
                                            false
                                    )
                            )
                            .addLayers(
                                    EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS,
                                    new EquipmentClientInfo.Layer(
                                            Helpers.identifier(name),
                                            Optional.empty(),
                                            false
                                    )
                            )
                            .addLayers(
                                    EquipmentClientInfo.LayerType.HORSE_BODY,
                                    new EquipmentClientInfo.Layer(
                                            Helpers.identifier(name),
                                            Optional.empty(),
                                            false
                                    )
                            )
                            .build()
            );
        }else {
            registrar.accept(
                    Helpers.identifier(name),
                    builder
                            .addLayers(
                                    EquipmentClientInfo.LayerType.HUMANOID,
                                    new EquipmentClientInfo.Layer(
                                            Helpers.identifier(name),
                                            Optional.empty(),
                                            false
                                    )
                            )
                            .addLayers(
                                    EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS,
                                    new EquipmentClientInfo.Layer(
                                            Helpers.identifier(name),
                                            Optional.empty(),
                                            false
                                    )
                            )
                            .build()
            );
        }

    }

    /**
     * 添加装备
     * @param map 装备Map
     * @param armorName 装备名称
     */
    private void add(Map<ResourceLocation, EquipmentClientInfo> map, String armorName) {
        add((name, info) -> {
            if (map.putIfAbsent(name, info) != null) {
                throw new IllegalStateException("Tried to register equipment client info twice for id: " + name);
            }
        }, armorName, false);
    }

    /**
     * 添加装备
     * @param map 装备Map
     * @param armorName 装备名称
     * @param hasHorseArmor 是否有马甲
     */
    private void add(Map<ResourceLocation, EquipmentClientInfo> map, String armorName, boolean hasHorseArmor) {
        add((name, info) -> {
            if (map.putIfAbsent(name, info) != null) {
                throw new IllegalStateException("Tried to register equipment client info twice for id: " + name);
            }
        }, armorName, hasHorseArmor);
    }

    @Override
    public CompletableFuture<?> run(CachedOutput cache) {
        Map<ResourceLocation, EquipmentClientInfo> map = new HashMap<>();
        loadArmors(map);
        return DataProvider.saveAll(cache, EquipmentClientInfo.CODEC, this.pathProvider, map);
    }

    /**
     * 加载装备
     * @param map 装备Map
     */
    public void loadArmors(Map<ResourceLocation, EquipmentClientInfo> map) {
        add(map, "ruby", true);
        add(map, "amber");
        add(map, "emerald");
        add(map, "silver");
    }

    @Override
    public String getName() {
        return "Equipment Client Infos: " + ExtraPlus.MOD_ID;
    }
}
